package com.zhang.crowd.mvc.handler;
import com.github.pagehelper.PageInfo;
import com.zhang.crowd.constant.CrowdConstant;
import com.zhang.crowd.entity.Admin;
import com.zhang.crowd.service.api.AdminService;
import com.zhang.crowd.util.ResultEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpSession;
import javax.xml.transform.Result;
import java.util.Enumeration;
import java.util.List;

@Controller
public class AdminHandler {

    @Autowired
    AdminService adminService;


    @RequestMapping("/admin/do/logout.html")
    public String doLogout(HttpSession session){
        //强制Session失效
        session.invalidate();

        return "redirect:/admin/to/login/page.html";
    }


    @RequestMapping("/admin/do/login.html")
    public String doLogin(
            @RequestParam("loginAcct") String loginAcct,
            @RequestParam("userPswd") String userPswd,
            HttpSession session
    ){
        //调用Service方法执行登录检查
        // 这个方法如果能够返回admin对象，说明登录成功，如果账号、密码不正确则会抛出异常
        Admin admin = adminService.getAdminByLoginAcct(loginAcct,userPswd);

        //将登录成功返回的admin对象存入Session域
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN,admin);

        //如果使用转发方式不使用重定向的话，页面刷新一次就会查一次库,由于不需要带任何数据，直接使用view-controller标签即可
        //这里的转发路径一定要加/表示从当前项目路径下重定向，不然就表示从当前请求目录下重定向
        //redirect: /adminxxxx 冒号:与路径之间不能有空格，不然会出错
        return "redirect:/admin/to/main/page.html";
    }


    @RequestMapping("/admin/get/page.html")
    public String getPageInfo(
            //使用@RequestParam注解的defaultValue属性，指定默认值，在请求中没有携带对应参数时使用默认值
            //keyword默认值使用时空字符串，和SQL语句配合实现两种情况适配
            @RequestParam(value = "keyword", defaultValue = "")String keyword,

            //pageNum默认值使用1
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,

            //pageSize默认值使用5
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            ModelMap modelMap
    ){
        //调用Service方法获取PageInfo对象
        PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword,pageNum,pageSize);
        //将PageInfo对象存入模型
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO,pageInfo);
        return "admin-page";
    }


    @RequestMapping("/admin/remove/{adminId}/{pageNum}/{keyword}.html")
    public String remove(@PathVariable("adminId") Integer adminId,
                         @PathVariable("pageNum") Integer pageNum,
                         @PathVariable("keyword") String keyword,
                         HttpSession session){
        Object obj = session.getAttribute("SPRING_SECURITY_CONTEXT");
        System.out.println(obj.getClass().toString());
        //这里由于加入了SpringSecurity原来的Session不能用了
     /*   Admin admin = (Admin) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN);
        String param = "";
        //如果删除的是自己的账户则提示不能删除
        if(admin.getId() == adminId){
            session.setAttribute("DeleteException",CrowdConstant.MESSAGE_ERROR_DELETE_SELF);
        }else {
            //执行删除
            session.removeAttribute("DeleteException");

        }*/
        adminService.remove(adminId);
        //页面跳转：回到分页页面
        // 尝试方案1：直接转发到admin-page.jsp会无法显示分页数据
        // return "admin-page";

        // 尝试方案2: 转发到/admin/get/page.html地址，一旦刷新页面会重复执行删除浪费性能
        // return "forward:/admin/get/page.html";

        //尝试方案3：重定向到/admin/get/page.html地址
        //同时为了保持原本所在的页面和查询关键词在附加pageNum和keyword两个请求参数
        return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
    }

    @PreAuthorize("hasAuthority('user:save')")
    @RequestMapping("/admin/save.html")
    public String save(Admin admin){
        adminService.saveAdmin(admin);
        return "redirect:/admin/get/page.html?pageNum="+Integer.MAX_VALUE;
    }

    /**
     * 由于这是采用的是转发请求的方式，都是同一个请求，所以不用在
     * 参数列表中去设置pageNum和keyword等参数
     * 直接在前端页面中放在隐藏域中即可
     * @param adminId
     * @param modelMap
     * @return
     */
    @RequestMapping("/admin/to/edit/page.html")
    public String toEditPage(
            @RequestParam("adminId") Integer adminId,
            ModelMap modelMap
    ){
        //根据adminId查找admin对象
        Admin admin = adminService.getAdminById(adminId);

        //将查找到的admin对象存入模型
        modelMap.addAttribute("admin",admin);
        return "admin-edit";
    }



    @RequestMapping("/admin/update.html")
    public String updateAdmin(Admin admin,@RequestParam("pageNum") Integer pageNum,@RequestParam("keyword") String keyword){

        adminService.updateAdmin(admin);
        return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
    }

    //PreFilter：在方法执行前对传入的参数进行过滤。只能对集合类型的数据进行过滤
    //PostFilter:在方法执行后对方法返回值进行过滤。只能对集合类型的数据进行过滤。
    @PreFilter(value = "filterObject%2==0")
    @ResponseBody
    @RequestMapping("/admin/test/pre/filter")
    public ResultEntity<List<Integer>> saveList(@RequestBody List<Integer> valueList){
        return ResultEntity.successWithData(valueList);
    }
}
